﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DispatchFuction
{
    public struct Step
    {
        #region 指令
        /// <summary>
        /// 开始
        /// </summary>
        public bool start;
        /// <summary>
        /// 继续
        /// </summary>
        public bool continues;
        /// <summary>
        /// 暂停
        /// </summary>
        public bool pause;
        /// <summary>
        /// 停止
        /// </summary>
        public bool stop;
        /// <summary>
        /// 结束
        /// </summary>
        public bool end;
        /// <summary>
        /// 延时跳步
        /// </summary>
        public int junpStep;
        /// <summary>
        /// 立即跳步
        /// </summary>
        public int immedJunpStep;
        /// <summary>
        /// 延时步进
        /// </summary>
        public bool condition;
        /// <summary>
        /// 立即步进
        /// </summary>
        public bool immedCondition;
        /// <summary>
        /// 启用完成序列验证
        /// </summary>
        public bool enableSequenceCheck;
        #endregion

        #region 输入参数
        /// <summary>
        /// 请求序列
        /// </summary>
        public int requestSequence;
        /// <summary>
        /// 结束序列
        /// </summary>
        public int endSequence;
        /// <summary>
        /// 步进延时
        /// </summary>
        public int stepDelay;

        #endregion

        #region 执行参数
        /// <summary>
        /// 目标步号
        /// </summary>
        public int tarStepNo;
        /// <summary>
        /// 当前步号
        /// </summary>
        public int stepNo;
        /// <summary>
        /// 请求响应
        /// </summary>
        public int acknowledgeSequence;
        /// <summary>
        /// 完成应答
        /// </summary>
        public int responseSequence;
        /// <summary>
        /// 启动序列
        /// </summary>
        public int startSequence;
        #endregion


        #region 状态
        /// <summary>
        /// 存在执行步
        /// </summary>
        public bool haveStep;
        /// <summary>
        /// 运行中
        /// </summary>
        public bool run;
        /// <summary>
        /// 暂停中
        /// </summary>
        public bool paused;
        /// <summary>
        /// 已停止
        /// </summary>
        public bool stoped;
        /// <summary>
        /// 已完成
        /// </summary>
        public bool done;
        /// <summary>
        /// 准备开始
        /// </summary>
        public bool readForStart;
        /// <summary>
        /// 准备继续
        /// </summary>
        public bool readForContinue;
        /// <summary>
        /// 步延
        /// </summary>
        public bool pulse;
        /// <summary>
        /// 继续延
        /// </summary>
        public bool continuePulse;
        /// <summary>
        /// 新步延
        /// </summary>
        public bool newPulse;
        /// <summary>
        /// 启动延
        /// </summary>
        public bool startRis;
        /// <summary>
        /// 继续延
        /// </summary>
        public bool continueRis;
        /// <summary>
        /// 暂停延
        /// </summary>
        public bool pauseRis;
        /// <summary>
        /// 停止延
        /// </summary>
        public bool stopRis;
        /// <summary>
        /// 完成延
        /// </summary>
        public bool doneRis;
        /// <summary>
        /// 运行上升延
        /// </summary>
        public bool runRis;
        /// <summary>
        /// 运行下降延
        /// </summary>
        public bool runFal;
        #endregion
    }
    public struct Task
    {
        #region 指令
        /// <summary>
        /// 开始
        /// </summary>
        public bool start;
        /// <summary>
        /// 继续
        /// </summary>
        public bool continues;
        /// <summary>
        /// 暂停
        /// </summary>
        public bool pause;
        /// <summary>
        /// 停止
        /// </summary>
        public bool stop;
        /// <summary>
        /// 结束
        /// </summary>
        public bool end;
        /// <summary>
        /// 使能
        /// </summary>
        public bool enable;
        /// <summary>
        /// 故障输入
        /// </summary>
        public bool alarm;
        /// <summary>
        /// 启用完成序列验证
        /// </summary>
        public bool enableSequenceCheck;
        #endregion

        #region 输入参数
        /// <summary>
        /// 请求序列
        /// </summary>
        public int requestSequence;
        /// <summary>
        /// 结束序列
        /// </summary>
        public int endSequence;
        #endregion

        #region 执行参数
        /// <summary>
        /// 请求响应
        /// </summary>
        public int acknowledgeSequence;
        /// <summary>
        /// 完成应答
        /// </summary>
        public int responseSequence;
        /// <summary>
        /// 启动序列
        /// </summary>
        public int startSequence;
        #endregion


        #region 状态
        /// <summary>
        /// 存在执行步
        /// </summary>
        public bool haveTask;
        /// <summary>
        /// 运行中
        /// </summary>
        public bool run;
        /// <summary>
        /// 暂停中
        /// </summary>
        public bool paused;
        /// <summary>
        /// 已停止
        /// </summary>
        public bool stoped;
        /// <summary>
        /// 已完成
        /// </summary>
        public bool done;
        /// <summary>
        /// 准备开始
        /// </summary>
        public bool readForStart;
        /// <summary>
        /// 准备继续
        /// </summary>
        public bool readForContinue;
        /// <summary>
        /// 使能中
        /// </summary>  
        public bool enabled;
        /// <summary>
        /// 报警中
        /// </summary>
        public bool alarming;
        /// <summary>
        /// 启动延
        /// </summary>
        public bool startRis;
        /// <summary>
        /// 继续延
        /// </summary>
        public bool continueRis;
        /// <summary>
        /// 暂停延
        /// </summary>
        public bool pauseRis;
        /// <summary>
        /// 停止延
        /// </summary>
        public bool stopRis;
        /// <summary>
        /// 完成延
        /// </summary>
        public bool doneRis;
        /// <summary>
        /// 运行上升延
        /// </summary>
        public bool runRis;
        /// <summary>
        /// 运行下降延
        /// </summary>
        public bool runFal;
        #endregion
    }
    public class Dispatch_Step
    {
        private Step step;
        private int stepNoTemp;
        private bool delayIn;
        private bool delaytemp;
        private bool delayOut;
        private Int64 lastDelayTime;
        private AutoResetEvent resetEvent;

        public Dispatch_Step()
        {
            resetEvent=new AutoResetEvent(true);
            step = new Step();
            step.tarStepNo = -1;
            step.stepNo = -1;
            step.immedJunpStep = -1;
            step.junpStep = -1;
        }
        /// <summary>
        /// 执行步
        /// </summary>
        public Step Step
        {
            get { return step; }
            set
            {
                step.start = value.start;
                step.continues = value.continues;
                step.pause = value.pause;
                step.stop = value.stop;
                step.end = value.end;
                step.condition = value.condition;
                step.immedCondition = value.immedCondition;
                step.junpStep = value.junpStep;
                step.immedJunpStep = value.immedJunpStep;
                step.enableSequenceCheck = value.enableSequenceCheck;
                step.requestSequence = value.requestSequence;
                step.endSequence = value.endSequence;
                step.stepDelay = value.stepDelay;
            }
        }
        public void Invoke()
        {
            if (resetEvent.WaitOne(0))
            {
                try
                {
                    #region 状态
                    //开始就绪
                    step.readForStart = !step.haveStep;
                    //继续就绪
                    step.readForContinue = step.paused;
                    //复位延
                    step.startRis = false;
                    step.doneRis = false;
                    step.continueRis = false;
                    step.stopRis = false;
                    step.pauseRis = false;
                    step.runRis = false;
                    step.runFal = false;
                    //开始
                    if (step.readForStart && step.start)
                    {
                        step.haveStep = true;
                        step.run = true;
                        step.startRis = true;
                        step.runRis = true;

                        step.tarStepNo = 0;
                        step.acknowledgeSequence = step.requestSequence;
                        step.startSequence += 1;
                    }
                    //继续
                    if (step.readForContinue && step.continues)
                    {
                        step.run = true;
                        step.paused = false;
                        step.continueRis = true;
                        step.runRis = true;

                        step.stepNo = step.tarStepNo;
                    }
                    //暂停
                    if (step.run && step.pause)
                    {
                        step.run = false;
                        step.paused = true;
                        step.pauseRis = true;
                        step.runFal = true;

                        step.stepNo = -2;
                    }
                    //完成
                    if (step.haveStep && step.end && (!step.enableSequenceCheck || step.enableSequenceCheck && step.startSequence == step.endSequence))
                    {
                        step.haveStep = false;
                        step.run = false;
                        step.done = true;
                        step.doneRis = true;
                        step.runFal = true;
    
                        step.tarStepNo = -1;
                        step.stepNo = -1;
                        step.responseSequence = step.acknowledgeSequence;
                    }
                    //停止
                    if (step.haveStep && step.stop)
                    {
                        step.haveStep = false;
                        step.run = false;
                        step.stoped = true;
                        step.stopRis = true;
                        step.runFal = true;

                        step.tarStepNo = -1;
                        step.stepNo = -1;
                    }
                    //开始就绪
                    step.readForStart = !step.haveStep;
                    //继续就绪
                    step.readForContinue = step.paused;
                    #endregion

                    #region 执行步
                    //延时条件
                    delayIn = step.run && (step.condition || step.junpStep >= 0);
                    if (delayIn && !delaytemp) lastDelayTime = System.Environment.TickCount64;
                    delaytemp = delayIn;
                    delayOut = delayIn && !step.pulse && ((System.Environment.TickCount64 - lastDelayTime) >= step.stepDelay || System.Environment.TickCount64 < lastDelayTime);
                    //步进
                    if (step.run)
                    {
                        if (step.immedJunpStep >= 0) step.tarStepNo = step.immedJunpStep;
                        else if (step.immedCondition) step.tarStepNo += 1;
                        else if (delayOut && step.junpStep >= 0) step.tarStepNo = step.junpStep;
                        else if (delayOut && step.condition) step.tarStepNo += 1;
                        step.stepNo = step.tarStepNo;
                    }
                    //步延
                    step.pulse = step.run && step.stepNo != stepNoTemp;
                    step.continuePulse = step.pulse && stepNoTemp == -2;
                    step.newPulse = step.pulse && !step.continuePulse;
                    stepNoTemp = step.stepNo;
                    #endregion

                    #region 复位控制
                    step.start = false;
                    step.continues = false;
                    step.pulse = false;
                    step.stop = false;
                    step.end = false;
                    step.condition = false;
                    step.immedCondition = false;
                    step.junpStep = -1;
                    step.immedJunpStep = -1;
                    if (step.pulse || !step.run) step.stepDelay = 0;
                    #endregion
                }
                finally
                {
                    resetEvent.Set();
                } 
            }
        }
    }
    public class Dispatch_Task
    {
        private Task task;
        private bool innerPause;
        private AutoResetEvent resetEvent;

        public Dispatch_Task()
        {
            resetEvent = new AutoResetEvent(true);
            task=new Task();
        }
        /// <summary>
        /// 执行步
        /// </summary>
        public Task Task
        {
            get { return task; }
            set
            {
                task.start = value.start;
                task.continues = value.continues;
                task.pause = value.pause;
                task.stop = value.stop;
                task.end = value.end;
                task.enableSequenceCheck = value.enableSequenceCheck;
                task.requestSequence = value.requestSequence;
                task.endSequence = value.endSequence;
            }
        }
        public void Invoke()
        {
            if (resetEvent.WaitOne(0))
            {
                try
                {
                    #region 状态
                    //内部暂停
                    innerPause = !task.enable || task.alarm;
                    //开始就绪
                    task.readForStart = !task.haveTask && !innerPause;
                    //继续就绪
                    task.readForContinue = task.paused && !innerPause;
                   //复位延
                    task.startRis = false;
                    task.doneRis = false;
                    task.continueRis = false;
                    task.stopRis = false;
                    task.pauseRis = false;
                    task.runRis = false;
                    task.runFal = false;
                    task.enabled = task.enable;
                    task.alarming = task.alarm;
                    //开始
                    if (!task.haveTask && task.start)
                    {
                        task.haveTask = true;
                        task.run = true;
                        task.startRis = true;
                        task.runRis = true;

                        task.acknowledgeSequence = task.requestSequence;
                        task.startSequence += 1;
                    }
                    //继续
                    if (task.readForContinue && task.continues)
                    {
                        task.run = true;
                        task.paused = false;
                        task.continueRis = true;
                        task.runRis = true;

                    }
                    //暂停
                    if (task.run && task.pause)
                    {
                        task.run = false;
                        task.paused = true;
                        task.pauseRis = true;
                        task.runFal = true;

                    }
                    //完成
                    if (task.haveTask &&
                        !task.startRis &&
                        task.end &&
                        (!task.enableSequenceCheck || task.enableSequenceCheck && task.startSequence == task.endSequence))
                    {
                        task.haveTask = false;
                        task.run = false;
                        task.done = true;
                        task.doneRis = true;
                        task.runFal = true;

                        task.responseSequence = task.acknowledgeSequence;
                    }
                    //停止
                    if (task.haveTask && task.stop)
                    {
                        task.haveTask = false;
                        task.run = false;
                        task.stoped = true;
                        task.stopRis = true;
                        task.runFal = true;
                    }
                    //开始就绪
                    task.readForStart = !task.haveTask && !innerPause;
                    //继续就绪
                    task.readForContinue = task.paused && !innerPause;
                    #endregion

                    #region 复位控制
                    task.start = false;
                    task.continues = false;
                    task.stop = false;
                    task.end = false;
                    task.enable = false;
                    task.alarm = false;
                    #endregion
                }
                finally
                {
                    resetEvent.Set();
                }
            }
        }
    }
}
